#include "show.h"
#include "cmsis_os2.h"
#include "FreeRTOS.h"
#include "oled.h"
#include "semphr.h"
#include "main.h"
#include "link.h"

extern SemaphoreHandle_t semHandle;
extern EnvInfo gInfo;
extern uint8_t gMenu;

EnvInfo preInfo = {0};
uint8_t curMenu = 0;
TimeInfo preTime = {0};

uint8_t Get_Number_Len(uint16_t number)
{
	if (number == 0)
		return 1;
	
	int len = 0;
	
	while (number > 0)
	{
		len++;
		number /= 10;
	}
	
	return len;
}

void Show_OLED_Light(uint8_t level)
{
	OLED_WR_CMD(0x81);
	
	switch(level)
	{
		case 1:
			OLED_WR_CMD(0x0f);
			break;
		case 2:
			OLED_WR_CMD(0x8f);
			break;
		default:
			OLED_WR_CMD(0xff);
			break;
	}
}

void Show_Environment(void)
{
	uint8_t temp, humi, i;
	uint16_t light;
	
	xSemaphoreTake(semHandle, portMAX_DELAY);
	temp = gInfo.temp;
	humi = gInfo.humi;
	light = gInfo.light;
	xSemaphoreGive(semHandle);
	
	if (gMenu != curMenu)
	{
		for (i = 0; i < 16; i++)
			OLED_ShowChar(i * 8, 4, '-', 16);
		
		OLED_Clearrow(6);
		OLED_Clearrow(7);
		
		OLED_ShowChinese(40, 6, 10);
		OLED_ShowChar(90, 6, '%', 16);
	}
	
	uint8_t len = Get_Number_Len(light);
	
	if (light != preInfo.light || gMenu != curMenu)
	{
		for (i = 0; i < 4; i++)
			OLED_Clearrow(i);
		
		if (len % 2)
			OLED_ShowNum((8 - len) / 2 * 16 + 8, 0, light, len, 32);
		else
			OLED_ShowNum((8 - len) / 2 * 16, 0, light, len, 32);
	}
	
	if (temp != preInfo.temp || gMenu != curMenu)
	{
		len = Get_Number_Len(temp);
		if (len == 1)
		{
			OLED_ShowString(20, 6, (uint8_t *)"  ", 16);
			OLED_ShowNum(28, 6, temp, len, 16);
		}
		else
		{
			OLED_ShowNum(20, 6, temp, len, 16);
		}
	}
	
	if (humi != preInfo.humi || gMenu != curMenu)
	{
		OLED_ShowNum(70, 6, humi, 2, 16);
	}
	
	preInfo.humi = humi;
	preInfo.temp = temp;
	preInfo.light = light;
}

void Show_Time(void)
{
	if (curMenu != gMenu)
	{
		OLED_Clear();
		
		OLED_ShowChinese(16 * 2, 0, 11);
		OLED_ShowChinese(16 * 3, 0, 12);
		OLED_ShowChinese(16 * 4, 0, 13);
		OLED_ShowChinese(16 * 5, 0, 14);
		
		OLED_ShowChinese(80, 2, 15);
		OLED_ShowChinese(96, 2, 16);
	}
	
	uint8_t x_pos = 0;
	uint32_t curTime = gInfo.cur_time + 3600 * 8;
	struct tm *t = localtime(&curTime);
	
	uint16_t year = t->tm_year + 1900;
	uint8_t month = t->tm_mon + 1;
	uint8_t day = t->tm_mday;
	uint8_t hour = t->tm_hour;
	uint8_t min = t->tm_min;
	uint8_t sec = t->tm_sec;
	uint8_t week = t->tm_wday;
	
	if (year != preTime.year || gMenu != curMenu)
	{
		OLED_ShowNum(x_pos, 2, year, 4, 16);
	}
	
	x_pos += 32;
	
	if (gMenu != curMenu)
	{
		OLED_ShowChar(x_pos, 2, '-', 16);
	}
	
	x_pos += 8;
	
	if (month != preTime.month || gMenu != curMenu)
	{
		OLED_ShowNum(x_pos, 2, month, Get_Number_Len(month), 16);
	}
	
	if (Get_Number_Len(month) == 1)
		x_pos += 8;
	else
		x_pos += 16;
	
	if (gMenu != curMenu)
	{
		OLED_ShowChar(x_pos, 2, '-', 16);
	}
	
	x_pos += 8;
	
	if (day != preTime.day || gMenu != curMenu)
	{
		OLED_ShowNum(x_pos, 2, day, Get_Number_Len(day), 16);
	}
	
	if (Get_Number_Len(day) == 1)
		x_pos += 8;
	else
		x_pos += 16;
	
	if (week != preTime.week || gMenu != curMenu)
	{
		OLED_ShowChinese(112, 2, week + 16);
	}
	
	//set hour min sec
	x_pos = 0;
	if (hour != preTime.hour || gMenu != curMenu)
	{
		if (hour < 10)
		{
			OLED_ShowNum(x_pos, 4, 0, 1, 32);
			x_pos += 16;
			OLED_ShowNum(x_pos, 4, hour, 1, 32);
			x_pos += 16;
		}
		else 
		{
			OLED_ShowNum(x_pos, 4, hour, 2, 32);
			x_pos += 32;
		}
	}
	else
	{
		x_pos += 32;
	}
	
	if (gMenu != curMenu)
	{
		OLED_ShowChar(x_pos, 4, ':', 32);
	}
	
	x_pos += 16;
	
	if (min != preTime.min || gMenu != curMenu)
	{
		if (min < 10)
		{
			OLED_ShowNum(x_pos, 4, 0, 1, 32);
			x_pos += 16;
			OLED_ShowNum(x_pos, 4, min, 1, 32);
			x_pos += 16;
		}
		else 
		{
			OLED_ShowNum(x_pos, 4, min, 2, 32);
			x_pos += 32;
		}
	}
	else
	{
		x_pos += 32;
	}
	
	if (gMenu != curMenu)
	{
		OLED_ShowChar(x_pos, 4, ':', 32);
	}
	
	x_pos += 16;
	
	if (sec != preTime.sec || gMenu != curMenu)
	{
		if (sec < 10)
		{
			OLED_ShowNum(x_pos, 4, 0, 1, 32);
			x_pos += 16;
			OLED_ShowNum(x_pos, 4, sec, 1, 32);
			x_pos += 16;
		}
		else 
		{
			OLED_ShowNum(x_pos, 4, sec, 2, 32);
			x_pos += 32;
		}
	}
	else
	{
		x_pos += 32;
	}
	
	preTime.year = year;
	preTime.month = month;
	preTime.day = day;
	preTime.hour = hour;
	preTime.min = min;
	preTime.sec = sec;
	preTime.week = week;
}

void Show_Alarm(void)
{
	uint8_t hour, min, x_pos = 16;
	
	Link_Find_Alarm(&hour, &min);
	
	if (gMenu != curMenu)
	{
		OLED_Clear();
		
		OLED_ShowChinese(16 * 3, 0, 24);
		OLED_ShowChinese(16 * 4 + 8, 0, 25);
	}
	
	if (gMenu != curMenu || hour != preTime.hour)
	{
		if (hour < 10)
		{
			OLED_ShowNum(x_pos, 3, 0, 1, 40);
			x_pos += 20;
			OLED_ShowNum(x_pos, 3, hour, 1, 40);
			x_pos += 20;
		}
		else 
		{
			OLED_ShowNum(x_pos, 3, hour, 2, 40);
			x_pos += 40;
		}
	}
	else
	{
		x_pos += 40;
	}
	
	if (gMenu != curMenu)
		OLED_ShowChar(x_pos, 3, ':', 40);
	
	x_pos += 20;
	
	if (gMenu != curMenu || min != preTime.min)
	{
		if (min < 10)
		{
			OLED_ShowNum(x_pos, 3, 0, 1, 40);
			x_pos += 20;
			OLED_ShowNum(x_pos, 3, min, 1, 40);
			x_pos += 20;
		}
		else 
		{
			OLED_ShowNum(x_pos, 3, min, 2, 40);
			x_pos += 40;
		}
	}
	else
	{
		x_pos += 40;
	}
	
	preTime.hour = hour;
	preTime.min = min;
}

void Show_Note(void)
{
	uint8_t hour = 0, min = 0, thing = 0, x_pos = 24;
	
	if (gMenu != curMenu)
	{
		OLED_Clear();
		
		OLED_ShowChinese(16 * 2 + 8, 0, 26);
		OLED_ShowChinese(16 * 3 + 8, 0, 27);
		OLED_ShowChinese(16 * 4 + 8, 0, 28);
	}
	
	Link_Find_Note(&hour, &min, &thing);
	
	if (gMenu != curMenu || hour != preTime.hour)
	{
		if (hour < 10)
		{
			OLED_ShowNum(x_pos, 2, 0, 1, 32);
			x_pos += 16;
			OLED_ShowNum(x_pos, 2, hour, 1, 32);
			x_pos += 16;
		}
		else 
		{
			OLED_ShowNum(x_pos, 2, hour, 2, 32);
			x_pos += 32;
		}
	}
	else
	{
		x_pos += 32;
	}
	
	OLED_ShowChar(x_pos, 2, ':', 32);
	
	x_pos += 16;
	
	if (gMenu != curMenu || min != preTime.min)
	{
		if (min < 10)
		{
			OLED_ShowNum(x_pos, 2, 0, 1, 32);
			x_pos += 16;
			OLED_ShowNum(x_pos, 2, min, 1, 32);
			x_pos += 16;
		}
		else 
		{
			OLED_ShowNum(x_pos, 2, min, 2, 32);
			x_pos += 32;
		}
	}
	else
	{
		x_pos += 32;
	}
	
	if (thing == 0)
	{
		OLED_Clearrow(6);
		OLED_Clearrow(7);
		
		preTime.hour = hour;
		preTime.min = min;
		preTime.thing = thing;
		
		return;
	}
	
	if (thing == 1)
		x_pos = 16;
	else if (thing == 2 || thing == 3)
		x_pos = 24;
	
	if (curMenu != gMenu || preTime.thing != thing)
	{
		OLED_Clearrow(6);
		OLED_Clearrow(7);
	}
	
	OLED_ShowChinese(x_pos, 6, 29);
	x_pos += 16;
	OLED_ShowChinese(x_pos, 6, 30);
	x_pos += 16;
	OLED_ShowChinese(x_pos, 6, 31);
	x_pos += 16;
	
	if (curMenu != gMenu || preTime.thing != thing)
	{	
		if (thing == 1)
		{
			OLED_ShowChinese(x_pos, 6, 34);
			x_pos += 16;
			OLED_ShowChinese(x_pos, 6, 35);
			x_pos += 16;
			OLED_ShowChinese(x_pos, 6, 36);
			x_pos += 16;
		}
		else if (thing == 2)
		{
			OLED_ShowChinese(x_pos, 6, 37);
			x_pos += 16;
			OLED_ShowChinese(x_pos, 6, 38);
			x_pos += 16;
		}
		else if (thing == 3)
		{
			OLED_ShowChinese(x_pos, 6, 32);
			x_pos += 16;
			OLED_ShowChinese(x_pos, 6, 33);
			x_pos += 16;
		}
	}
	
	preTime.hour = hour;
	preTime.min = min;
	preTime.thing = thing;
}

void OLED_Show_Menu(void)
{	
	OLED_Clear();
	uint8_t light;
	
	while (1)
	{
		xSemaphoreTake(semHandle, portMAX_DELAY);
		light = gInfo.light;
		xSemaphoreGive(semHandle);

		if (light < 20)
			Show_OLED_Light(1);
		else if (light < 40)
			Show_OLED_Light(2);
		else
			Show_OLED_Light(3);
		
		if (gMenu == 1)
		{
			Show_Environment();
			curMenu = gMenu;
		}
		else if (gMenu == 2)
		{
			Show_Time();
			curMenu = gMenu;
		}
		else if (gMenu == 3)
		{
			Show_Alarm();
			curMenu = gMenu;
		}
		else if (gMenu == 4)
		{
			Show_Note();
			curMenu = gMenu;
		}
		
		osDelay(250);
	}
}
